home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xgrabsc / process.hc < prev    next >
Text File  |  1995-05-09  |  8KB  |  282 lines

  1. /*========================================================================
  2.  *
  3.  * Name - process.hc
  4.  *
  5.  * ccs version:    1.2
  6.  *
  7.  * ccsid:    @(#)process.hc    1.2 - 07/06/92 10:52:51
  8.  * from:     ccs/s.process.hc
  9.  * date:     06/28/93 09:14:49
  10.  *
  11.  * Description:  color processing functions for xgrabsc
  12.  *
  13.  *               see cpyright.h for copyright information
  14.  *
  15.  *
  16.  *========================================================================
  17.  */
  18.  
  19. /*
  20.  * Alter colors by setting or clearing bits in rgb values.
  21.  * This effectively reduces the depth of the image, causing the
  22.  * number of colors used to be reduced.  Equivalent colors are
  23.  * merged in the image, and the used flags of remapped colors are
  24.  * cleared.
  25.  *
  26.  * The number of eliminated colormap entries is returned.  The colormap
  27.  * is not compressed.
  28.  */
  29. alterPlanes(image, modeIsAnd, bits)
  30.   imageInfo *image;
  31.   int modeIsAnd;      /* if TRUE, combine mask with AND; if FALSE, use OR */
  32.   unsigned int bits;
  33. {
  34.   int nc, cidx, ridx, h, w;
  35.   long p;
  36.   XImage *ximage = image->ximage;
  37.   long map[MAX_CELLS];
  38.   int remapCount;
  39.   word mask;
  40.  
  41.   if (ximage->depth <= 1)
  42.     return 0;
  43.  
  44.   mask = 0xFFFF ^ ((1 << (bits+8)) - 1);
  45.   if (!modeIsAnd)
  46.     mask = ~mask & 0xFFFF;
  47.  
  48.   if (verbose) {
  49.     fprintf(stderr, "%s: %s color with mask %x...", programName,
  50.             modeIsAnd? "ANDing" : "ORing", mask);
  51.     fflush(stderr);
  52.   }
  53.  
  54.   nc = image->numcells;
  55.   if (modeIsAnd)
  56.     for (cidx=0; cidx<nc; cidx++) {
  57.       nr[cidx] = image->red[cidx]   & mask;
  58.       ng[cidx] = image->green[cidx] & mask;
  59.       nb[cidx] = image->blue[cidx]  & mask;
  60.     }
  61.   else
  62.     for (cidx=0; cidx<nc; cidx++) {
  63.       nr[cidx] = image->red[cidx]   | mask;
  64.       ng[cidx] = image->green[cidx] | mask;
  65.       nb[cidx] = image->blue[cidx]  | mask;
  66.     }
  67.  
  68.   /* now eliminate redundant colors */
  69.   for (cidx=0; cidx<nc; cidx++)
  70.     map[cidx] = cidx;
  71.   remapCount = 0;
  72.   for (cidx=0; cidx<nc; cidx++)
  73.     if (image->used[cidx])
  74.       for (ridx=cidx+1; ridx<nc; ridx++)
  75.         if (image->used[ridx]  &&
  76.             nr[cidx]==nr[ridx] &&
  77.             ng[cidx]==ng[ridx] &&
  78.             nb[cidx]==nb[ridx]) {
  79.           /* the colors match - remap this pixel to the one we're scanning with */
  80.           map[ridx] = cidx;
  81.           image->used[ridx] = FALSE;
  82.           remapCount++;
  83.         }
  84.  
  85.   memcpy((char *)image->red,   (char *)nr, nc*sizeof(word));
  86.   memcpy((char *)image->green, (char *)ng, nc*sizeof(word));
  87.   memcpy((char *)image->blue,  (char *)nb, nc*sizeof(word));
  88.  
  89.   /* remap redundant pixels in the image */
  90.   if (remapCount)
  91.     for (h=0; h<ximage->height; h++)
  92.       for (w=0; w<ximage->width; w++) {
  93.         p = XGetPixel(ximage, w, h);
  94.         if (p != map[p])
  95.           XPutPixel(ximage, w, h, map[p]);
  96.       }
  97.  
  98.   if (verbose)
  99.     fprintf(stderr, "  %d colors remapped\n", remapCount, nc);
  100.   return remapCount;
  101. }
  102.  
  103.  
  104.  
  105.  
  106.  
  107. /* Brighten or darken colors in the image by the given amount ('percent').
  108.  * The amount is an integer that, if less than 100 will darken the image
  109.  * and if greater than 100 will brighten the image.  After modifying
  110.  * colors equivalent colors are merged (as in alterPlanes).  The number
  111.  * of eliminated colors is returned.
  112.  */
  113. brightenColors(image, percent)
  114.   imageInfo *image;
  115.   int percent;
  116. {
  117.   int nc, cidx, ridx, h, w;
  118.   long p;
  119.   XImage *ximage = image->ximage;
  120.   float  adjustment;
  121.   long map[MAX_CELLS];
  122.   int remapCount;
  123.   dw new;
  124.  
  125.   if (ximage->depth <= 1)
  126.     return 0;
  127.  
  128.   if (verbose) {
  129.     fprintf(stderr, "%s: adjusting intensity by %d...", programName, percent);
  130.     fflush(stderr);
  131.   }
  132.  
  133.   adjustment = (float)percent / 100.0;
  134.   nc = image->numcells;
  135.   for (cidx=0; cidx<nc; cidx++) {
  136.     new = image->red[cidx] * adjustment;
  137.     if (new > (dw)0xFFFF) new = (dw)0xFFFF;
  138.     nr[cidx] = new;
  139.     new = image->green[cidx] * adjustment;
  140.     if (new > (dw)0xFFFF) new = (dw)0xFFFF;
  141.     ng[cidx] = new;
  142.     new = image->blue[cidx] * adjustment;
  143.     if (new > (dw)0xFFFF) new = (dw)0xFFFF;
  144.     nb[cidx] = new;
  145.   }
  146.  
  147.   /* now eliminate redundant colors */
  148.   for (cidx=0; cidx<nc; cidx++)
  149.     map[cidx] = cidx;
  150.   remapCount = 0;
  151.   for (cidx=0; cidx<nc; cidx++)
  152.     if (image->used[cidx])
  153.       for (ridx=cidx+1; ridx<nc; ridx++)
  154.         if (image->used[ridx]  &&
  155.             nr[cidx]==nr[ridx] &&
  156.             ng[cidx]==ng[ridx] &&
  157.             nb[cidx]==nb[ridx]) {
  158.           map[ridx] = cidx;
  159.           image->used[ridx] = FALSE;
  160.           remapCount++;
  161.         }
  162.  
  163.   memcpy((char *)image->red,   (char *)nr, nc*sizeof(word));
  164.   memcpy((char *)image->green, (char *)ng, nc*sizeof(word));
  165.   memcpy((char *)image->blue,  (char *)nb, nc*sizeof(word));
  166.  
  167.   /* remap redundant pixels in the image */
  168.   if (remapCount)
  169.     for (h=0; h<ximage->height; h++)
  170.       for (w=0; w<ximage->width; w++) {
  171.         p = XGetPixel(ximage, w, h);
  172.         if (p != map[p])
  173.           XPutPixel(ximage, w, h, map[p]);
  174.       }
  175.  
  176.  
  177.   if (verbose)
  178.     fprintf(stderr, "  %d colors remapped\n", remapCount, nc);
  179.  
  180.   return remapCount;
  181. }
  182.  
  183.  
  184.  
  185.  
  186.  
  187. /* Reverse the colors in the image */
  188. reverseColors(image)
  189.   imageInfo *image;
  190. {
  191.   int nc, cidx;
  192.   long size, idx;
  193.   unsigned char *data;
  194.   XImage *ximage;
  195.   int map[2];
  196.  
  197.   if (verbose) {
  198.     fprintf(stderr, "%s: reversing colors...", programName);
  199.     fflush(stderr);
  200.   }
  201.  
  202.  
  203.   if (image->ximage->depth <= 1) {
  204.     /* for black and white images, just reverse the bits */
  205.     ximage = image->ximage;
  206.     data = (unsigned char *)ximage->data;
  207.     size = ximage->bytes_per_line * ximage->height;
  208.     for (idx=0; idx<size; idx++, data++)
  209.       *data = ~(*data);
  210.   }
  211.   else {
  212.     /* for other images, reverse the color values in the color table */
  213.     nc = image->numcells;
  214.     for (cidx=0; cidx<nc; cidx++) {
  215.       image->red[cidx]   = (unsigned short)~((unsigned short)(image->red[cidx]));
  216.       image->blue[cidx]  = (unsigned short)~((unsigned short)(image->blue[cidx]));
  217.       image->green[cidx] = (unsigned short)~((unsigned short)(image->green[cidx]));
  218.     }
  219.   }
  220. }
  221.  
  222.  
  223.  
  224.  
  225.  
  226. /*
  227.  * Compress the colors used in an XImage so that all pixel values are
  228.  * adjacent.  Alters the rgb color tables and the XImage data values.
  229.  */
  230. compressColormap(image)
  231.   imageInfo *image;
  232. {
  233.   XImage *ximage = image->ximage;
  234.   long map[MAX_CELLS];
  235.   int  ncolors, w, h, m;
  236.   long p;
  237.  
  238.   if (ximage->depth <= 1  ||  image->numcells > MAX_CELLS)
  239.     return;
  240.  
  241.   if (verbose) {
  242.     fprintf(stderr, "%s: compressing colormap...", programName);
  243.     fflush(stderr);
  244.   }
  245.   ncolors = 0;
  246.   /* map[] is indexed by old pixel values.  It delivers new, compressed,
  247.    * pixel values. */
  248.   for (m=0; m<MAX_CELLS; m++) map[m] = MAX_CELLS+1;
  249.   /* bludgeon through the whole image and remap each pixel value */
  250.   for (h=0; h<ximage->height; h++) {
  251.     for (w=0; w<ximage->width; w++) {
  252.       /* Get the pixel index and see if it has been used or not.
  253.        * Then remap the pixel */
  254.       p = XGetPixel(ximage, w, h);
  255.       if (map[p] == MAX_CELLS+1) {
  256.         map[p] = ncolors;
  257.         ncolors++;
  258.       }
  259.       if (p != map[p])
  260.         XPutPixel(ximage, w, h, map[p]);
  261.     }
  262.   }
  263.   /* now compress the color table */
  264.   memset((char *)image->used, 0, MAX_CELLS);
  265.   for (m=0; m<MAX_CELLS; m++) {
  266.     if (map[m] != MAX_CELLS+1) {
  267.       p = map[m];
  268.       nr[p] = image->red[m];
  269.       ng[p] = image->green[m];
  270.       nb[p] = image->blue[m];
  271.       image->used[p] = TRUE;
  272.     }
  273.   }
  274.   memcpy((char *)image->red,   (char *)nr, ncolors*sizeof(word));
  275.   memcpy((char *)image->green, (char *)ng, ncolors*sizeof(word));
  276.   memcpy((char *)image->blue,  (char *)nb, ncolors*sizeof(word));
  277.   image->numcells = ncolors;
  278.   if (verbose)
  279.     fprintf(stderr, "  %d colors used\n", ncolors);
  280. }
  281.  
  282.